from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from sqlalchemy import desc, asc, or_, and_, func
from typing import Optional, List
from database import get_db, get_redis
from models import AITool
from schemas import ResponseModel, AIToolSearchResponse, TrendingResponse
import json
from datetime import datetime, timedelta

router = APIRouter(prefix="/api/search", tags=["搜索"])

@router.get("/tools", response_model=ResponseModel)
async def search_ai_tools(
    q: str = Query(..., description="搜索关键词"),
    page: int = Query(1, ge=1, description="页码"),
    limit: int = Query(10, ge=1, le=50, description="每页数量"),
    category: Optional[str] = Query(None, description="工具分类过滤"),
    sort: str = Query("relevance", description="排序方式: relevance/rating/popularity/name"),
    db: Session = Depends(get_db)
):
    """
    搜索AI工具
    
    Args:
        q: 搜索关键词
        page: 页码
        limit: 每页数量
        category: 工具分类过滤
        sort: 排序方式
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含搜索结果的响应
    """
    # 记录搜索关键词到Redis（用于热门搜索统计）
    redis_client = get_redis()
    if redis_client:
        try:
            # 增加搜索次数
            redis_client.zincrby("search_keywords", 1, q.lower())
            # 设置过期时间（7天）
            redis_client.expire("search_keywords", 7 * 24 * 3600)
        except Exception as e:
            print(f"Redis操作失败: {e}")
    
    # 构建搜索查询
    query = db.query(AITool).filter(AITool.is_active == True)
    
    # 关键词搜索（在名称、描述、标签中搜索）
    search_terms = q.strip().split()
    search_conditions = []
    
    for term in search_terms:
        term_condition = or_(
            AITool.name.ilike(f"%{term}%"),
            AITool.description.ilike(f"%{term}%"),
            func.json_contains(AITool.tags, f'"{term}"')  # MySQL JSON包含操作
        )
        search_conditions.append(term_condition)
    
    if search_conditions:
        query = query.filter(and_(*search_conditions))
    
    # 分类过滤
    if category:
        query = query.filter(AITool.category == category)
    
    # 排序
    if sort == "rating":
        query = query.order_by(desc(AITool.rating))
    elif sort == "popularity":
        query = query.order_by(desc(AITool.popularity))
    elif sort == "name":
        query = query.order_by(asc(AITool.name))
    else:  # relevance - 默认按相关性排序（这里简化为按评分和热度综合排序）
        query = query.order_by(desc(AITool.rating + AITool.popularity / 1000))
    
    # 获取总数
    total = query.count()
    
    # 分页
    offset = (page - 1) * limit
    tools = query.offset(offset).limit(limit).all()
    
    # 转换为响应格式
    results = []
    for tool in tools:
        results.append({
            "id": tool.id,
            "name": tool.name,
            "description": tool.description,
            "icon": tool.icon,
            "url": tool.url,
            "category": tool.category,
            "tags": tool.tags or [],
            "rating": tool.rating / 10.0,  # 转换为0-5.0的评分
            "popularity": tool.popularity
        })
    
    return ResponseModel(
        code=200,
        message="success",
        data={
            "total": total,
            "page": page,
            "limit": limit,
            "results": results
        }
    )

@router.get("/trending", response_model=ResponseModel)
async def get_trending_keywords(
    limit: int = Query(10, ge=1, le=20, description="返回数量")
):
    """
    获取热门搜索关键词
    
    Args:
        limit: 返回数量
    
    Returns:
        ResponseModel: 包含热门关键词的响应
    """
    redis_client = get_redis()
    keywords = []
    
    if redis_client:
        try:
            # 从Redis获取热门搜索关键词（按搜索次数降序）
            trending = redis_client.zrevrange("search_keywords", 0, limit - 1)
            keywords = [keyword.decode() if isinstance(keyword, bytes) else keyword for keyword in trending]
        except Exception as e:
            print(f"Redis操作失败: {e}")
    
    # 如果Redis中没有数据，返回默认热门关键词
    if not keywords:
        keywords = ["ChatGPT", "Midjourney", "文心一言", "Stable Diffusion", "Claude"]
    
    return ResponseModel(
        code=200,
        message="success",
        data={
            "keywords": keywords[:limit]
        }
    )

@router.get("/suggestions", response_model=ResponseModel)
async def get_search_suggestions(
    q: str = Query(..., description="搜索关键词前缀"),
    limit: int = Query(5, ge=1, le=10, description="返回数量"),
    db: Session = Depends(get_db)
):
    """
    获取搜索建议
    
    Args:
        q: 搜索关键词前缀
        limit: 返回数量
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含搜索建议的响应
    """
    suggestions = []
    
    if len(q.strip()) >= 2:  # 至少2个字符才提供建议
        # 从工具名称中搜索匹配的建议
        tools = db.query(AITool.name).filter(
            AITool.name.ilike(f"%{q}%"),
            AITool.is_active == True
        ).limit(limit).all()
        
        suggestions = [tool.name for tool in tools]
        
        # 如果建议不够，从Redis热门搜索中补充
        if len(suggestions) < limit:
            redis_client = get_redis()
            if redis_client:
                try:
                    # 获取包含关键词的热门搜索
                    all_keywords = redis_client.zrevrange("search_keywords", 0, -1)
                    matching_keywords = [
                        keyword.decode() if isinstance(keyword, bytes) else keyword 
                        for keyword in all_keywords 
                        if q.lower() in (keyword.decode() if isinstance(keyword, bytes) else keyword).lower()
                    ]
                    
                    # 补充建议
                    for keyword in matching_keywords:
                        if keyword not in suggestions and len(suggestions) < limit:
                            suggestions.append(keyword)
                except Exception as e:
                    print(f"Redis操作失败: {e}")
    
    return ResponseModel(
        code=200,
        message="success",
        data={
            "suggestions": suggestions
        }
    )

@router.get("/categories", response_model=ResponseModel)
async def get_tool_categories(
    db: Session = Depends(get_db)
):
    """
    获取AI工具分类列表
    
    Args:
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含分类列表的响应
    """
    # 查询所有活跃工具的分类及其数量
    categories = db.query(
        AITool.category,
        func.count(AITool.id).label('count')
    ).filter(
        AITool.is_active == True
    ).group_by(
        AITool.category
    ).order_by(
        desc('count')
    ).all()
    
    category_data = []
    for category, count in categories:
        category_data.append({
            "name": category,
            "count": count
        })
    
    return ResponseModel(
        code=200,
        message="success",
        data={
            "categories": category_data
        }
    )

@router.get("/popular", response_model=ResponseModel)
async def get_popular_tools(
    limit: int = Query(10, ge=1, le=20, description="返回数量"),
    category: Optional[str] = Query(None, description="分类过滤"),
    db: Session = Depends(get_db)
):
    """
    获取热门AI工具
    
    Args:
        limit: 返回数量
        category: 分类过滤
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含热门工具的响应
    """
    query = db.query(AITool).filter(AITool.is_active == True)
    
    # 分类过滤
    if category:
        query = query.filter(AITool.category == category)
    
    # 按热度排序
    tools = query.order_by(desc(AITool.popularity)).limit(limit).all()
    
    results = []
    for tool in tools:
        results.append({
            "id": tool.id,
            "name": tool.name,
            "description": tool.description,
            "icon": tool.icon,
            "url": tool.url,
            "category": tool.category,
            "tags": tool.tags or [],
            "rating": tool.rating / 10.0,
            "popularity": tool.popularity
        })
    
    return ResponseModel(
        code=200,
        message="success",
        data={
            "tools": results
        }
    )

@router.post("/record-click", response_model=ResponseModel)
async def record_tool_click(
    tool_id: int,
    db: Session = Depends(get_db)
):
    """
    记录工具点击（用于统计热度）
    
    Args:
        tool_id: 工具ID
        db: 数据库会话
    
    Returns:
        ResponseModel: 记录结果
    
    Raises:
        HTTPException: 如果工具不存在
    """
    tool = db.query(AITool).filter(AITool.id == tool_id).first()
    
    if not tool:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="工具不存在"
        )
    
    # 增加热度值
    tool.popularity += 1
    db.commit()
    
    return ResponseModel(
        code=200,
        message="记录成功",
        data=None
    )